<template>
  <template v-if="!isText">
    <el-input :style="{
      width: proxy.$size(width, '100%'),
    }" v-model="keyword" v-bind="{
      placeholder: '请输入',
      clearable: true,
      ...$attrs,
      disabled: !!dataName ? (typeof $attrs.disabled === 'function' ? $attrs.disabled(data) : $attrs.disabled) : true
    }" @change="changeBtn">
      <template #[key] v-for="(_, key) in $slots">
        <slot :name="key" />
      </template>
      <template #append v-if="!!$attrs.unit">
        {{ $attrs.unit }}
      </template>
    </el-input>
  </template>
  <TextBox :data="keyword" :unit="$attrs.unit" v-else />
</template>
<script setup lang="ts">
import { all, create } from 'mathjs';
import { getCurrentInstance, onMounted } from 'vue';
const { proxy } = getCurrentInstance() as any;
//获取父级数据
const props = withDefaults(
  defineProps<{
    data: any; //主体
    dataName?: string; //key值
    width?: string | number; //宽度
    precision?: number; //小数精度
    isText?: boolean;//文本
  }>(),
  {
    precision: 9
  },
);
const emit = defineEmits<{
  //fn为父组件引入子组件是定义的子组件事件属性，可随意定义
  (event: 'changeBtn', val: any, row: any): void;
  (event: 'keydownBtn', val: any, row: any): void;
}>();
const keyword = computed({
  get() {
    let _number: any = null;
    if (props.dataName) {
      _number = props.data[props.dataName];
    } else {
      _number = props.data;
    }
    if (_number === Infinity) {
      _number = null
      if (props.dataName) {
        props.data[props.dataName] = _number;
      }
    }
    return _number;
  },
  set(val) {
    let _number = null
    if (typeof val === 'string') {
      // 移除非允许的字符：仅允许数字、小数点、括号、+-*/=
      let cleaned = props.precision === 0 ? val.replace(/[^0-9+\-*()/=]/g, '') : val.replace(/[^0-9+\-*()/.=]/g, '');
      //判断是否有精度
      if (props.precision > 0) {
        let parts = cleaned.split('.');
        if (parts.length > 1) { // 如果有小数部分
          // 限制小数位数
          parts[1] = parts[1].slice(0, props.precision);
          cleaned = parts.join('.');
        }
      }
      _number = cleaned;
      //判断是否有等号
      if (_number.includes('=')) {
        // 移除非允许的字符
        _number = _number.replace(/=(?=.*=)|=(?![^=]*^)/g, '');
        _number = '=' + _number;
      } else {
        _number = _number.replace(/[^0-9.-]/g, '');
      }
    }
    if (props.dataName) {
      props.data[props.dataName] = _number;
    } else {
      props.data = _number;
    }
  },
});
// 配置 math.js 使用 Decimal 类型
const math = create(all, {
  number: 'BigNumber', // 使用 BigNumber 类型
  precision: props.precision + 1, // 设置所需的精度
});
//判断等式是否成功
const safeEval = (expression: string) => {
  try {
    // 使用 Function 构造器代替 eval，以避免直接执行任意代码带来的风险
    // 注意：这仍然需要对输入进行严格的验证和清理
    return math.evaluate(expression);
  } catch (e) {
    ElMessage.error('无效的表达式');
    return null;
  }
};
const changeBtn = (value: string) => {
  let _number: any = value;
  // 确保等号只出现在第一个位置
  if (_number.includes('=')) {
    const expression = _number.substring(1);
    _number = safeEval(expression);
  }
  const _attrs: any = proxy.$attrs
  //判断是否有最大值
  if ((_attrs.max || _attrs.max === 0) && _number > _attrs.max) {
    _number = _attrs.max
    ElMessage.error(`不能超过最大值${_number}`);
  }
  //判断是否有最小值
  if ((_attrs.min || _attrs.min === 0) && _number < _attrs.min) {
    _number = _attrs.min
    ElMessage.error(`不能小于最小值${_number}`);
  }
  _number = _number || _number === 0 ? Number(_number) : null;
  if (props.dataName) {
    props.data[props.dataName] = _number;
  } else {
    props.data = _number;
  }
  emit('changeBtn', value ? Number(value) : value, props.data);
};
// 组件挂载后执行
onMounted(() => {

});
</script>
<style scoped></style>
